package mysql

import (
	"easyShop/core/config"
	"errors"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"strconv"
	"sync"
)

var dataSources config.DataSources
var databaseSourceMap = make(map[string]config.DataWorker)
var dataCenterIndex = 0
var workerIndex = 0

// GetNextDataCenterIdAndWorkerId 获取下一个数据中心id和工作机器id
func GetNextDataCenterIdAndWorkerId() (int, int) {
	if dataSources == nil {
		dataSources = config.GetConfig("dataSources").(config.DataSources)
	}
	var s sync.Mutex
	s.Lock()
	// 如果工作机器索引大于当前数据中心里面工作机器的数量，则数据中心索引向后加一位，工作机器索引归0
	if workerIndex >= len(dataSources[dataCenterIndex]) {
		dataCenterIndex++
		workerIndex = 0
	}

	// 如果数据中心的索引大于所有的数据中心数，则数据中心索引归0
	if dataCenterIndex >= len(dataSources) {
		dataCenterIndex = 0
	}
	currentDataCenterIndex := dataCenterIndex
	currentWorkerIndex := workerIndex
	workerIndex++
	s.Unlock()

	return dataSources[currentDataCenterIndex][currentWorkerIndex].DataCenterId, dataSources[currentDataCenterIndex][currentWorkerIndex].WorkerId
}

// GetDatabaseSourceMap 获取以（数据中心id_工作机器id）为键值的数据库配置列表
func GetDatabaseSourceMap() map[string]config.DataWorker {
	if len(databaseSourceMap) > 0 {
		return databaseSourceMap
	}
	if dataSources == nil {
		dataSources = config.GetConfig("dataSources").(config.DataSources)
	}
	for i := 0; i < len(dataSources); i++ {
		for n := 0; n < len(dataSources[i]); n++ {
			databaseSourceMap[strconv.Itoa(dataSources[i][n].DataCenterId)+"_"+strconv.Itoa(dataSources[i][n].WorkerId)] = dataSources[i][n]
		}
	}

	return databaseSourceMap
}

// GetDatabaseConfigByDataCenterIdAndWorkerId 根据数据中心id和机器id获取对应的数据库配置
func GetDatabaseConfigByDataCenterIdAndWorkerId(dataCenterId int, workerId int) config.DataWorker {
	return databaseSourceMap[strconv.Itoa(dataCenterId)+"_"+strconv.Itoa(workerId)]
}

// GetConnectByDataCenterIdAndWorkerId 根据数据中心id和机器id获取数据库连接
func GetConnectByDataCenterIdAndWorkerId(dataCenterId int, workerId int) (*gorm.DB, error) {
	databaseConfig := GetDatabaseConfigByDataCenterIdAndWorkerId(dataCenterId, workerId)
	user := databaseConfig.User
	pass := databaseConfig.Password
	host := databaseConfig.Host
	port := databaseConfig.Port
	dbName := databaseConfig.DbName
	charset := databaseConfig.Charset
	dsn := user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + dbName + "?charset=" + charset + "&parseTime=True&loc=Local"
	con, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		SkipDefaultTransaction: true,
		Logger:                 logger.Default.LogMode(logger.Silent),
	})
	if err != nil {
		return con, errors.New("链接数据库异常")
	}
	return con, nil
}

// GetNextConnect 获取根据下一个数据中心id和工作机器id得到的数据库链接
func GetNextConnect() (*gorm.DB, error) {
	dataCenterId, workerId := GetNextDataCenterIdAndWorkerId()
	conn, err := GetConnectByDataCenterIdAndWorkerId(dataCenterId, workerId)
	return conn, err
}
